﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BreukTrainer.Model;
using System.Threading;

namespace BreukTrainer.View
{
    public partial class OefenenMetBreuken : Form
    {
        private DataTable breukenDT;
        private DataTable breukenOpgavenDT;
        private DataTable breukenSorterenDT;
        private ProgrammeerbareBreukContainer breukContainer;
        private List<Breuk> breukenListGesorteerd;
        private int timerCount;
        private String[] oplossingen;
        private String[] opgaven;

        public OefenenMetBreuken()
        {
            InitializeComponent();
        }

        private void OefenenMetBreuken_Load(object sender, EventArgs e)
        {
            // DataTable BREUKEN
            breukenDT = new DataTable();
            breukenDT.Columns.Add("#");
            breukenDT.Columns.Add("Breuk");
            breukenDT.Rows.Add("1","");
            breukenDT.Rows.Add("2","");
            dataGridViewBreuken.RowHeadersVisible = false;
            dataGridViewBreuken.DataSource = breukenDT;
            dataGridViewBreuken.Columns[0].Width = 20;
            dataGridViewBreuken.Columns[0].ReadOnly = true;
            // DataTable BREUKEN OPGAVEN
            breukenOpgavenDT = new DataTable();
            breukenOpgavenDT.Columns.Add("Opgave");
            breukenOpgavenDT.Columns.Add("Antwoord");
            breukenOpgavenDT.Columns.Add("*");
            dataGridViewOpgaven.RowHeadersVisible = false;
            dataGridViewOpgaven.DataSource = breukenOpgavenDT;
            dataGridViewOpgaven.Columns[0].Width = 200;
            dataGridViewOpgaven.Columns[0].ReadOnly = true;
            dataGridViewOpgaven.Columns[1].Width = 60;
            dataGridViewOpgaven.Columns[2].Width = 60;
            dataGridViewOpgaven.Columns[2].ReadOnly = true;
            // DataTable BREUKEN SORTEREN
            breukenSorterenDT = new DataTable();
            breukenSorterenDT.Columns.Add("Breuk");
            dataGridViewSorteren.RowHeadersVisible = false;
            dataGridViewSorteren.DataSource = breukenSorterenDT;
            dataGridViewSorteren.Columns[0].Width = 100;
            dataGridViewSorteren.Columns[0].ReadOnly = true;

            breukContainer = new ProgrammeerbareBreukContainer();
        }

        private void AantalBreukenNum_ValueChanged(object sender, EventArgs e)
        {
            int aantalBreuken = (int)AantalBreukenNum.Value;
            breukenDT.Rows.Clear();
            for (int i = 0; i < aantalBreuken; i++)
            {
                breukenDT.Rows.Add(i + 1, "");
            }
        }

        private void dataGridViewBreuken_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            try
            {
                dataGridViewBreuken.Rows[e.RowIndex].ErrorText = "";
                if (e.ColumnIndex == 1 && !e.FormattedValue.ToString().Equals(""))
                {
                    String input = e.FormattedValue.ToString();
                    int teller, noemer;
                    if (input.Contains('/'))
                    {
                        String[] inputSplit = input.Split('/');
                        teller = int.Parse(inputSplit[0]);
                        noemer = int.Parse(inputSplit[1]);
                    }
                    else
                    {
                        teller = int.Parse(input);
                        noemer = 1;
                    }
                    breukContainer.AddBreuk(new Breuk(teller, noemer));
                }
            }
            catch (Exception ex)
            {
                e.Cancel = true;
                dataGridViewBreuken.Rows[e.RowIndex].ErrorText = ex.ToString();
                MessageBox.Show("Fout formaat voor breuk!\n\nError: " + ex.ToString(), "Invoer Breuk", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void checkWelkeBreuken(object sender, EventArgs e)
        {
            if (radioButtonZelfBreukenIngeven.Checked) {
                breukContainer = new ProgrammeerbareBreukContainer();
                dataGridViewBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)AantalBreukenNum.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            } 
            else { 
                dataGridViewBreuken.Enabled = false; 
            }
            if (radioButtonBreukenLatenGenererenZonderBeperkingen.Checked) { 
                buttonMaakBreuken.Enabled = true;
                breukContainer = new ProgrammeerbareBreukContainer();
                dataGridViewBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)AantalBreukenNum.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            } 
            else { 
                buttonMaakBreuken.Enabled = false; 
            }
            if (radioButtonEenvoudigeBreukenGenereren.Checked) { 
                buttonMaakBreukenGrens.Enabled = true; 
                textBoxOndergrens.Enabled = true; 
                textBoxBovengrens.Enabled = true;
                breukContainer = new ProgrammeerbareBreukContainer();
                dataGridViewBreuken.Enabled = true; breukenDT.Rows.Clear();
                for (int i = 0; i < (int)AantalBreukenNum.Value; i++)
                {
                    breukenDT.Rows.Add(i + 1, "");
                }
            } 
            else { 
                buttonMaakBreukenGrens.Enabled = false; 
                textBoxOndergrens.Enabled = false; 
                textBoxBovengrens.Enabled = false; 
            }
        }

        private void checkWelkeBewerkingen(object sender, EventArgs e)
        {
            if (radioButtonRandombewerkingenOpAlleBreuken.Checked) { textBoxAantalOpgaven.Enabled = true; } else { textBoxAantalOpgaven.Enabled = false; }
            if (checkBoxAntwoordenMetTijdslimiet.Checked) { textBoxAantalSeconden.Enabled = true; progressBar.Enabled = true; progressBar.Visible = true; } else { textBoxAantalSeconden.Enabled = false; progressBar.Enabled = false; progressBar.Visible = false; }
        }

        private void buttonMaakBreuken_Click(object sender, EventArgs e)
        {
            breukenDT.Rows.Clear();
            for (int i = 0; i < (int)AantalBreukenNum.Value; i++)
            {
                Breuk breuk = Breuk.RandomBreuk(-9999, 9999); // toch een limiet ingesteld om leesbaar te houden !!!
                breuk.Vereenvoudig();
                breukContainer.AddBreuk(breuk);
                breukenDT.Rows.Add(i + 1, breuk.Toon());
            }
        }

        private void buttonMaakBreukenGrens_Click(object sender, EventArgs e)
        {
            int onderGrens, bovenGrens;
            if (int.TryParse(textBoxOndergrens.Text, out onderGrens) && int.TryParse(textBoxBovengrens.Text, out bovenGrens))
            {
                if (bovenGrens > onderGrens)
                {
                    breukenDT.Rows.Clear();
                    breukContainer = new ProgrammeerbareBreukContainer();
                    for (int i = 0; i < (int)AantalBreukenNum.Value; i++)
                    {
                        Breuk breuk = Breuk.RandomBreuk(onderGrens, bovenGrens);
                        breuk.Vereenvoudig();
                        breukContainer.AddBreuk(breuk);
                        breukenDT.Rows.Add(i + 1, breuk.Toon());
                    }
                }
                else
                {
                    MessageBox.Show("De bovengrens moet groter zijn dan de ondergrens!", "Ongeldige invoer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
            else
            {
                MessageBox.Show("Geef geldige onder- en bovengrens!", "Ongeldige invoer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void buttonMaakOpgaven_Click(object sender, EventArgs e)
        {
            if (breukContainer.AantalBreuken() > 1)
            {
                dataGridViewOpgaven.Columns[0].ReadOnly = true;
                if (radioButtonBasisbewerkingen.Checked) maakOpgavenBasisberwerkingen();
                if (radioButtonRandombewerkingenOpAlleBreuken.Checked) maakOpgavenRandombewerkingen();
                maakSorteer();

                if (checkBoxAntwoordenMetTijdslimiet.Checked)
                {
                    int aantalSeconden;
                    try
                    {
                        aantalSeconden = int.Parse(textBoxAantalSeconden.Text);
                        progressBar.Minimum = 0;
                        progressBar.Maximum = aantalSeconden;
                        timer1.Interval = 1000;
                        timer1.Start();

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Geen geldige seconden!\n\nError: " + ex.ToString(), "Invoer Aantal Seconden", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
            }
            else MessageBox.Show("Er zijn niet genoeg breuken gemaakt");
        }

        private void maakOpgavenBasisberwerkingen()
        {
            breukenOpgavenDT.Rows.Clear();
            dataGridViewOpgaven.Columns[2].Visible = false;
            int aantalBreuken = breukContainer.AantalBreuken();
            String outOpt = "", outAft = "", outVer = "", outDel = "";
            String[] sOpt = new String[aantalBreuken - 1], sAft = new String[aantalBreuken - 1], sVer = new String[aantalBreuken - 1], sDel = new String[aantalBreuken - 1];
            DelegateBreukenBewerking[] dOpt = new DelegateBreukenBewerking[aantalBreuken], dAft = new DelegateBreukenBewerking[aantalBreuken], dVer = new DelegateBreukenBewerking[aantalBreuken], dDel = new DelegateBreukenBewerking[aantalBreuken];
            for (int i = 0; i < aantalBreuken; i++)
            {
                outOpt += dataGridViewBreuken.Rows[i].Cells[1].Value.ToString();
                outAft += dataGridViewBreuken.Rows[i].Cells[1].Value.ToString();
                outVer += dataGridViewBreuken.Rows[i].Cells[1].Value.ToString();
                outDel += dataGridViewBreuken.Rows[i].Cells[1].Value.ToString();
                if (i < aantalBreuken - 1)
                {
                    dOpt[i] = new DelegateBreukenBewerking(Breuk.TelOp);
                    dAft[i] = new DelegateBreukenBewerking(Breuk.TrekAf);
                    dVer[i] = new DelegateBreukenBewerking(Breuk.Vermenigvuldig);
                    dDel[i] = new DelegateBreukenBewerking(Breuk.Delen);
                    sOpt[i] = "+";
                    sAft[i] = "-";
                    sVer[i] = "*";
                    sDel[i] = "/";
                    outOpt += " + ";
                    outAft += " - ";
                    outVer += " * ";
                    outDel += " : ";
                }
            }
            Breuk[] uitkomstOpt = breukContainer.DoeBewerking(dOpt, sOpt);
            breukenOpgavenDT.Rows.Add(outOpt, "", ((Breuk)uitkomstOpt[0]).Toon());
            Breuk[] uitkomstAft = breukContainer.DoeBewerking(dAft, sAft);
            breukenOpgavenDT.Rows.Add(outAft, "", ((Breuk)uitkomstAft[0]).Toon());
            Breuk[] uitkomstVer = breukContainer.DoeBewerking(dVer, sVer);
            breukenOpgavenDT.Rows.Add(outVer, "", ((Breuk)uitkomstVer[0]).Toon());
            Breuk[] uitkomstDel = breukContainer.DoeBewerking(dDel, sDel);
            breukenOpgavenDT.Rows.Add(outDel, "", ((Breuk)uitkomstDel[0]).Toon());
        }

        private void maakOpgavenRandombewerkingen()
        {
            try
            {
                breukenOpgavenDT.Rows.Clear();
                dataGridViewOpgaven.Columns[2].Visible = false;
                int aantalBreuken = breukContainer.AantalBreuken();
                int aantalOpgaven = Int32.Parse(textBoxAantalOpgaven.Text);
                opgaven = new String[aantalOpgaven];
                oplossingen = new String[aantalOpgaven];
                String[] operandenRandom = { "+", "-", "*", "/" };
                Random randomGenerator = new Random();
                for (int i = 0; i < opgaven.Length; i++)
                {
                    //String[] operanden = new String[aantalOpgaven];
                    String[] operanden = new String[breukContainer.Breuken.Count];
                    //DelegateBreukenBewerking[] delegates = new DelegateBreukenBewerking[aantalOpgaven];
                    DelegateBreukenBewerking[] delegates = new DelegateBreukenBewerking[breukContainer.Breuken.Count];
                    for (int j = 0; j < breukContainer.Breuken.Count; j++)
                    {
                        if (j == breukContainer.Breuken.Count - 1)
                        {
                            opgaven[i] += breukContainer.Breuken[j].ToString();
                        }
                        else
                        {
                            operanden[j] = operandenRandom[randomGenerator.Next(0,3)];
                            opgaven[i] += breukContainer.Breuken[j].ToString() + " " + operanden[j] + " ";
                            switch (operanden[j])
                            {
                                case "+": delegates[j] = new DelegateBreukenBewerking(Breuk.TelOp); break;
                                case "-": delegates[j] = new DelegateBreukenBewerking(Breuk.TrekAf); break;
                                case "*": delegates[j] = new DelegateBreukenBewerking(Breuk.Vermenigvuldig); break;
                                case "/": delegates[j] = new DelegateBreukenBewerking(Breuk.Delen); break;
                            }
                        }
                    }
                    oplossingen[i] = breukContainer.TestIets(delegates, operanden).ToString();
                }
                if (checkBoxAntwoordenMetTijdslimiet.Checked)
                {
                    breukenOpgavenDT.Rows.Add(opgaven[0], "", oplossingen[0]);
                    timerCount = 1;
                    timer1.Start();
                }
                else
                {
                    for (int i = 0; i < aantalOpgaven; i++)
                    {
                        breukenOpgavenDT.Rows.Add(opgaven[i], "", oplossingen[i]);
                        dataGridViewOpgaven.Rows[i].ReadOnly = true;
                    }
                }
                
            }
            catch (FormatException e)
            {
                MessageBox.Show("Geen geldige invoer!\n\nError: " + e.Message, "Invoer Aantal Opgaven", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void shiznit(String[] opg, String[] opl)
        {
            
        }

        private void maakSorteer()
        {
            breukenSorterenDT.Rows.Clear();
            breukenListGesorteerd = breukContainer.Breuken;
            breukenListGesorteerd.Sort();
            foreach (Breuk breuk in breukenListGesorteerd)
            {
                breukenSorterenDT.Rows.Add(breuk.Toon());
            }
        }

        private void buttonEvalueer_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dataGridViewOpgaven.Rows.Count; i++)
            {
                DataGridViewRow currentRow = dataGridViewOpgaven.Rows[i];
                if (currentRow.Cells[1].Value.ToString().Length < 1)
                {
                    currentRow.Cells[1].Value = "X";
                }
                if (currentRow.Cells[1].Value.ToString().Equals(currentRow.Cells[2].Value.ToString()))
                {
                    currentRow.Cells[1].Style.BackColor = Color.Green;
                }
                else
                {
                    currentRow.Cells[1].Style.BackColor = Color.Red;
                }
                //currentRow.Cells[2].Style.ForeColor = Color.Green;
            }
        }

        private void buttonOplossingen_Click(object sender, EventArgs e)
        {
            dataGridViewOpgaven.Columns[2].Visible = true;
            buttonEvalueer_Click(sender, e);
        }

        private void buttonOmhoog_Click(object sender, EventArgs e)
        {
            
            List<Breuk> new_container = new List<Breuk>();
            int selectedIndex = dataGridViewSorteren.SelectedCells[0].RowIndex;
            if (selectedIndex != 0)
            {
                foreach (DataRow dr in breukenSorterenDT.Rows)
                {
                    int index = breukenSorterenDT.Rows.IndexOf(dr);
                    if (index == selectedIndex - 1)
                    {
                        new_container.Add(Breuk.StringToBreuk(breukenSorterenDT.Rows[selectedIndex].ItemArray[0].ToString()));
                        new_container.Add(Breuk.StringToBreuk(breukenSorterenDT.Rows[index].ItemArray[0].ToString()));
                    }
                    else if (!(index == selectedIndex))
                    {
                        new_container.Add(Breuk.StringToBreuk(dr.ItemArray[0].ToString()));
                    }
                }

                breukenSorterenDT.Rows.Clear();
                foreach (Breuk breuk in new_container)
                {
                    breukenSorterenDT.Rows.Add(breuk.Toon());
                }
                dataGridViewSorteren.Rows[selectedIndex - 1].Selected = true;
                dataGridViewSorteren.Rows[0].Selected = false;
            }

            //breukenSorterenDT.Rows[dataGridViewSorteren.SelectedCells[0].RowIndex].ItemArray[0].ToString();
        }

        private void buttonOmlaag_Click(object sender, EventArgs e)
        {
            List<Breuk> new_container = new List<Breuk>();
            int selectedIndex = dataGridViewSorteren.SelectedCells[0].RowIndex;
            int maxIndex = dataGridViewSorteren.Rows.Count - 1;
            if (selectedIndex != maxIndex)
            {
                foreach (DataRow dr in breukenSorterenDT.Rows)
                {
                    int index = breukenSorterenDT.Rows.IndexOf(dr);
                    if (index == selectedIndex)
                    {
                        new_container.Add(Breuk.StringToBreuk(breukenSorterenDT.Rows[index + 1].ItemArray[0].ToString()));
                        new_container.Add(Breuk.StringToBreuk(breukenSorterenDT.Rows[index].ItemArray[0].ToString()));
                    }
                    else if (index != selectedIndex +1)
                    {
                        new_container.Add(Breuk.StringToBreuk(breukenSorterenDT.Rows[index].ItemArray[0].ToString()));
                    }
                }

                breukenSorterenDT.Rows.Clear();
                foreach (Breuk breuk in new_container)
                {
                    breukenSorterenDT.Rows.Add(breuk.Toon());
                }
                dataGridViewSorteren.Rows[selectedIndex + 1].Selected = true;
                dataGridViewSorteren.Rows[0].Selected = false;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            progressBar.Increment(1);
            if (progressBar.Value == progressBar.Maximum)
            {
                dataGridViewOpgaven.Rows[timerCount-1].ReadOnly = true;
                progressBar.Value = 0;
                timer1.Stop();
                if (int.Parse(textBoxAantalOpgaven.Text) > timerCount)
                {
                    breukenOpgavenDT.Rows.Add(opgaven[timerCount], "", oplossingen[timerCount]);
                    timerCount++;
                    if (!(int.Parse(textBoxAantalOpgaven.Text) == timerCount))
                    {
                        timer1.Start();
                    }
                }
            }
        }

        

        
    }
}
